from typing import List, Optional, Dict, Any
from src import retMes, DB, str_utils as strU
from sqlalchemy.orm import Session
from src.models.sys_dict_header import SysDictHeader as SysDictHeaderModels
from src.models.sys_dict_value import SysDictValue as SysDictValueModels
from src.models.sys_dict_table import SysDictTable as SysDictTableModels
from src.schemas.login_manager import AuthManager
from pydantic import BaseModel


# ---------------------- 辅助：把 ORM 对象 → 前端所需字典 ----------------------
def _node_of(Dict: SysDictHeaderModels) -> Dict[str, Any]:
    return {

        "label": Dict.dict_name + '||' + Dict.dict_code,
        "name": Dict.dict_name,
        "code": Dict.dict_code,
    }


def dict_tree(db: Session,
              auth: AuthManager) -> dict:
    api_id = auth.api_id

    # 1. 全部启用菜单
    dicts = (db.query(SysDictHeaderModels)
             .filter(SysDictHeaderModels.api_id == api_id,
                     SysDictHeaderModels.deletion_mark == False)
             .order_by(SysDictHeaderModels.sort)
             .all())

    # 2. 建立两本字典
    id_2_node = {m.id: m for m in dicts}  # id → ORM 对象
    grouped: Dict[str, List[Dict[str, Any]]] = {}  # parent_id → 孩子列表

    for m in dicts:
        node = _node_of(m)
        # 把 id 也塞进字典，后面递归要用
        node["id"] = m.id
        node["dict_type"] = m.dict_type
        node["parent_id"] = m.parent_id
        grouped.setdefault(m.parent_id, []).append(node)

    # 3. 递归挂 children（用当前节点的 id 当 key）
    def attach_children(nodes: List[Dict[str, Any]]) -> List[Dict[str, Any]]:
        for node in nodes:
            kids = grouped.get(node["id"], [])  # ← 用 id 找孩子
            if kids:
                node["children"] = attach_children(kids)
        return nodes

    # 4. 从根节点（parent_id == "0"）开始
    tree = attach_children(grouped.get("0", []))
    return retMes.Success(tree).mes()


class DictItemOut(BaseModel):
    value: str
    label: str
    disabled: bool


rows: List[DictItemOut] = []


def _pick_value(row: Any, value_type: str) -> str:
    """row 可以是 ORM 对象或 JSON 字典"""

    key = 'id' if value_type == '1' else 'dict_code'
    return str(row[key])  # JSON 用 row[key]；ORM 用 row.key 也能自动转


def _pick_label(row: Any, text_type: str) -> str:
    if text_type == '2':
        return f"{row['dict_code']} {row['dict_text']}"
    return row['dict_text']


def dict_list(db: Session,
              auth: AuthManager,
              id: Optional[str] = None,
              dict_code: Optional[str] = None,
              ) -> dict:
    api_id = auth.api_id
    retVar = []
    if not (id or dict_code):
        return retVar
    query = db.query(SysDictHeaderModels).filter(
        SysDictHeaderModels.api_id == api_id,
        SysDictHeaderModels.deletion_mark == False
    )

    if id is not None:  # 优先按主键
        query = query.filter(SysDictHeaderModels.id == id)
    if dict_code is not None:  # 其次按编码
        query = query.filter(SysDictHeaderModels.dict_code == dict_code)

    dicts = query.order_by(SysDictHeaderModels.sort).all()
    base_values = []
    rows = []
    rows_root = []
    for dict in dicts:

        dict_type = dict.dict_type
        value_type = dict.value_type
        text_type = dict.text_type

        if dict_type == 'C':
            base_sql = (
                f"SELECT id, dict_code, dict_text, disabled "
                f"FROM sys_dict_value "
                f"WHERE api_id = {repr(api_id)} "  # repr 自动加单引号并转义
                f"AND dict_id = {repr(dict.id)} "
                f"ORDER BY sort"
            )
            base_values = DB.query(base_sql)
        elif dict_type == 'T':
            dict_tables = (db.query(SysDictTableModels)
                           .filter(SysDictTableModels.api_id == api_id,
                                   SysDictTableModels.deletion_mark == False,
                                   SysDictTableModels.dict_id == dict.id,
                                   )
                           .first()
                           )
            dict_root = dict_tables.dict_root
            if strU.convert_bool(dict_root):
                rows_root = dict_list(db, auth, dict_code='Root')
                rows.extend(rows_root)

            # 1. 基础 SELECT（注意把表名参数化，防止注入）
            base_sql = f"SELECT {dict_tables.dict_value} AS id, " \
                       f"{dict_tables.dict_code} AS dict_code, " \
                       f"{dict_tables.dict_text} AS dict_text, " \
                       f"{dict_tables.dict_disabled} AS disabled " \
                       f"FROM {dict_tables.table_name}"
            if dict_tables.conditional:
                base_sql += f"   {dict_tables.conditional}"
           
            base_values = DB.query(base_sql)

        base_values = strU.tranDict(base_values)
        for r in base_values:  # r 是 dict
            rows.append(DictItemOut(
                value=_pick_value(r, value_type=value_type),  # 取 id
                label=_pick_label(r, text_type=text_type),  # 拼接
                disabled=bool(r['disabled'])
            ))

            retVar = rows

    return retVar
